/*
 *
 *  Copyright (C) 2009 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see http://www.gnu.org/licenses/. 
 *
 *  Author : Raúl Román López <rroman@gsyc.es>
 *
 */

package com.LibreGeoSocial.App;

import java.io.IOException;
import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.LibreGeoSocial.Api.LibreGeoSocial;
import com.LibreGeoSocial.Api.User;
import com.LibreGeoSocial.App.GeoNames.AltitudeManager;
import com.LibreGeoSocial.App.Overlay.PositionOverlay;
import com.LibreGeoSocial.App.Routes.LocationService;
import com.LibreGeoSocial.App.Utils.MapUtils;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class LocationWays extends MapActivity {
	private MapView map;
	private MapController controller;
	private User user;
	private String usrpwd, usrtlf, message;
	public Location currentLocation = null;
	
	ProgressDialog pd = null;
	
	private static final int MENU_SATELLITE = Menu.FIRST + 1;
	private static final int MENU_LOCATION = Menu.FIRST + 2;
//	private static final int MENU_LOCATION_MOVISTAR = Menu.FIRST + 3;
//	private static final int MENU_LOCATION_IP = Menu.FIRST + 4;
	private static final int MENU_LOCATION_MANUAL = Menu.FIRST + 5;
	private static final int MENU_INDOOR_LOCATION = Menu.FIRST + 6;
	
	private static final int DIALOG_MANUAL_LOCATION = 2;
	
	private boolean capture = false;
	private GeoPoint map_center = null;
	
	public void init(){
		
//		map = (MapView) findViewById(R.id.locationMap);
		map = new MapView(this, getString(R.string.map_key));
		setContentView(map);
		controller = map.getController();

		//Adding a zoom control
		map.setBuiltInZoomControls(true);
		
		map.setClickable(true);
//		map.setOnTouchListener(touchListener);
		
		if(currentLocation!=null){
			setPositionInMap(17);
		}
		map.setSatellite(false);
		map.setStreetView(false);
		
		map_center = map.getMapCenter();
	}
	
    /** Called when the activity is first created. */
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        user = LibreGeoSocial.getInstance().getInfoUser(true, null);
        currentLocation = LocationService.getCurrentLocation();
        init();
        
    }
    
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev){
    	int zoom = map.getZoomLevel();
    	boolean res = super.dispatchTouchEvent(ev);
    	if(zoom == map.getZoomLevel()){
    		
			switch(ev.getAction()){
			
			case MotionEvent.ACTION_DOWN:

				map_center = map.getMapCenter();
				capture = true;
				break;
				
			case MotionEvent.ACTION_MOVE:
		    	GeoPoint new_map_center = map.getMapCenter();
		    	
		    	double distance = Math.sqrt(Math.pow(new_map_center.getLatitudeE6()-map_center.getLatitudeE6(),2)+
		    			Math.pow(new_map_center.getLongitudeE6()-map_center.getLongitudeE6(),2));
		    	
		    	map_center = new_map_center;
		    	
		    	if(distance > 1)
		    		capture = false;
		    	
				break;
			
			case MotionEvent.ACTION_UP:
				if (!capture)
					break;
				capture = false;
				
				Location loc = MapUtils.getLocFromXY(ev.getX(), ev.getY(), map, 0);
				
				setCurrentLocation(loc);
//				setPositionInMap(17);
				
				Toast.makeText(getBaseContext(), 
                        "Location updated", 
                        Toast.LENGTH_SHORT).show();
				break;
				
			default:
				if(Build.VERSION.SDK_INT > Build.VERSION_CODES.DONUT)
					capture = false;
				break;
			}
    		
    	}
    	
    	return res;
    }
    
	private void setPositionInMap(int zoom){
		
		GeoPoint point = new GeoPoint(  (int) (currentLocation.getLatitude() * 1E6), 
				  (int) (currentLocation.getLongitude() * 1E6));
		
		controller.animateTo(point);
		controller.setZoom(zoom);
		//OverlayItem marker = new OverlayItem(point, "You", "Now");
		PositionOverlay myposOverlay = new PositionOverlay();
        myposOverlay.setUser(user);
        //map.getOverlays().clear();
	    final List<Overlay> overlays = map.getOverlays();	   
	    overlays.add( myposOverlay );
	}
	
	private void setCurrentLocation(Location loc){
		currentLocation = loc;
		user.setLatitude(loc.getLatitude());
		user.setLongitude(loc.getLongitude());
		
		// getting altitude info
		double altitude = loc.getAltitude();
		
		if(altitude==0){
			altitude = AltitudeManager.getAltitudeFromLatLong((float) loc.getLatitude(), (float)loc.getLongitude());
			if(altitude < 0){
				Toast.makeText(getBaseContext(), 
						"Altitude not found", 
						Toast.LENGTH_LONG).show();
				altitude = 0;
			}
		}
		currentLocation.setAltitude(altitude);
		
		LibreGeoSocial.getInstance().setUserPosition(loc.getLatitude(), 
													 loc.getLongitude(),
													 altitude);
		LocationService.setCurrentLocation(currentLocation);
	}
	
    @Override
    protected Dialog onCreateDialog(int id) {
        
    	switch (id) {
		        
	    	case DIALOG_MANUAL_LOCATION:
	    		
	    		LayoutInflater factory3 = LayoutInflater.from(this);
	    		final View textEntryView3 = factory3.inflate(R.layout.manual, null);
	    		
	    		final EditText edit2 = (EditText) textEntryView3.findViewById (R.id.txtmanual);
	    		edit2.setText("");
	    		
		        return new AlertDialog.Builder(this)	        
		        .setTitle("Insert Address")
		        .setView(textEntryView3)
		        .setPositiveButton("search", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		            	if (!edit2.getText().toString().equals(""))
		            		searchManual(edit2.getText().toString());
		            	else
		            		Toast.makeText(getBaseContext(), 
		                            "Empty Address", 
		                            Toast.LENGTH_LONG).show();
		            }
		        })
		        .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
		            public void onClick(DialogInterface dialog, int whichButton) {
		
		                /* User clicked cancel so do some stuff */
		            }
		        })
		        .create();
	
	    }
    	
    	return null;
    }
	
    public void searchManual(String address){
		//manual = (LinearLayout) findViewById(R.id.loc_manual);

		Geocoder gcod = new Geocoder(getApplicationContext());
		try {
			List<Address> addressList = gcod.getFromLocationName(address, 1);

			if (addressList.isEmpty()){

				Toast.makeText(getBaseContext(), 
						"There's no address", 
						Toast.LENGTH_LONG).show();
			}
			if (addressList.get(0).hasLatitude() && addressList.get(0).hasLongitude()){
				
				Location loc = new Location("MANUAL_PROVIDER");
				loc.setLatitude(addressList.get(0).getLatitude());
				loc.setLongitude(addressList.get(0).getLongitude());
				
				setCurrentLocation(loc);
				setPositionInMap(15);
				//Send coordinates to the server
				Toast.makeText(getBaseContext(), 
                        "Location updated", 
                        Toast.LENGTH_SHORT).show();
			} else
				Toast.makeText(getBaseContext(), 
						"There are no coordinates", 
						Toast.LENGTH_LONG).show();

		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
//	public int searchMovistar(String user, String pwd){
//		double location[] = new double[3];
//		LocalizameAPI movistar = new LocalizameAPI();
//				
//		if(!movistar.login(user, pwd)){
//			message = "Service unavailable";
//			return 0;
//		}
//		
//		handlerRefresh.sendEmptyMessage(0);
//		if(!movistar.authorize(user)){
//			message = "Service unavailable";
//			return 0;
//		}
//		movistar.logout();
//
//		movistar.login(user,pwd);
//		handlerRefresh.sendEmptyMessage(1);
//		location = movistar.locate(user);
//		movistar.logout();
//
//		movistar.login(user, pwd);
//		handlerRefresh.sendEmptyMessage(2);
//		movistar.forbid(user);
//		movistar.logout();
//			
//		if(location==null){
//			message = "User unreachable";
//			return 0;
//		}
//		/*
//		location = new double[3];
//		location[0] = 40.3;
//		location[1] = -3.8;
//		location[2] = 927;
//		*/
//		
//		currentLocation = new Location("MOVISTAR_PROVIDER");
//		currentLocation.setLatitude(location[0]);
//		currentLocation.setLongitude(location[1]);
//		
//		//setCurrentLocation(currentLocation);
//		//setPositionInMap(calculateZoom(location[3]));
//		//Toast.makeText(getBaseContext(), "Tap on your location",Toast.LENGTH_LONG).show();
//		message = "Location updated";
//		
//		return ((int)location[2]);
//	}
	

	
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	
        super.onCreateOptionsMenu(menu);
        // Calling preferences   
	    SharedPreferences sharedPreferences = 
	    	PreferenceManager.getDefaultSharedPreferences(getBaseContext());

		// Reading Movistar Preferences
//		Boolean syncMovistar = 
//			sharedPreferences.getBoolean(LGS_Preferences.KEY_MOVISTAR_ACTIVE, false);
		
        menu.add(0, MENU_SATELLITE, 0, "Toggle satellite view")
				.setIcon(R.drawable.eye)
				.setAlphabeticShortcut('S');
        
        SubMenu sub = menu.addSubMenu (0, MENU_LOCATION, 0 , "Location")
        			  .setIcon(R.drawable.mundo);
        

//		if (syncMovistar){
//
//	        sub.add(0,MENU_LOCATION_MOVISTAR,0,"MOVISTAR");
//			
//		}
        
//        sub.add(0,MENU_LOCATION_IP,0,"IP");
        sub.add(0,MENU_LOCATION_MANUAL,0,"MANUAL");
        sub.add(0, MENU_INDOOR_LOCATION, 0, "BIDI Indoor location");
        
        return true;
    }

    @Override
    public boolean onOptionsItemSelected (MenuItem item) {
    	
    	switch (item.getItemId()) {
    		
    	case MENU_SATELLITE:
    		if (map.isSatellite())
	    		map.setSatellite(false);
	    	else
	    		map.setSatellite(true);
	        break;
    		
//    	case MENU_LOCATION_MOVISTAR:
//    		
//    		//showDialog(DIALOG_MOVISTAR_LOCATION);
//    		// Calling preferences   
//    		/*
//    	    SharedPreferences sharedPreferences = 
//    	    	PreferenceManager.getDefaultSharedPreferences(getBaseContext());
//    		
//    	    usrtlf = sharedPreferences.getString(LGS_Preferences.KEY_MOVISTAR_USER, "");
//    		usrpwd = sharedPreferences.getString(LGS_Preferences.KEY_MOVISTAR_LOCALIZAME_PWD, "");
//    		*/
//    		
//    		usrtlf = OMFManager.getPhone();
//    		usrpwd = OMFManager.getMovLocPwd();
//    		
//    		if (usrtlf.equals("") || usrpwd.equals("")){
//        		Toast.makeText(getBaseContext(), 
//                        "Insert data correctly in section 'movistar' from Home preferences menu", 
//                        Toast.LENGTH_LONG).show();
//        		break;
//        	}
//    		
//    		runMovistar();
//    	    
//    		break;
//    		
//    	case MENU_LOCATION_IP:
//    		
//    		int[] response = IPlocation.makePetition();
//    		
//    		if (response==null){
//    			Toast.makeText(getBaseContext(), 
//                        "IP location failed", 
//                        Toast.LENGTH_LONG).show();
//    			break;
//    		}
//			
//			Location loc = new Location("IP_PROVIDER");
//			loc.setLatitude(((double)response[0])/1E6);
//			loc.setLongitude(((double)response[1])/1E6);
//			
//			setCurrentLocation(loc);
//			setPositionInMap(calculateZoom((double)response[2]));
//
//			Toast.makeText(getBaseContext(), 
//                    "Location updated ", 
//                    Toast.LENGTH_SHORT).show();
//    		break;
    		
    	case MENU_LOCATION_MANUAL:
    	    
    		showDialog(DIALOG_MANUAL_LOCATION);
    		break;
    		
    	case MENU_INDOOR_LOCATION:
    		PackageManager pm = getPackageManager();
			List<ApplicationInfo> list = pm.getInstalledApplications(PackageManager.GET_META_DATA);
			boolean isBarcode = false;
			for(int i = 0; i< list.size(); i++){
				if( list.get(i).packageName.equals("com.google.zxing.client.android")){
					isBarcode = true;
					break;
				}
			}

			if (!isBarcode){
				Toast.makeText(getBaseContext(), 
						"Please, install Barcode Scanner from Market",
						Toast.LENGTH_LONG).show();
				break;
			}

			Intent intent = new Intent("com.google.zxing.client.android.SCAN");
			intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
			startActivityForResult(intent, MENU_INDOOR_LOCATION);
    		break;
    		
        }
    	
    	
        return super.onOptionsItemSelected(item);
    }
	
    protected void onActivityResult (int requestCode, int resultCode, Intent data) { 
		
		switch (requestCode) { 
	    	case MENU_INDOOR_LOCATION:

	    		if( resultCode != Activity.RESULT_CANCELED ){
	    			String contents = data.getStringExtra("SCAN_RESULT");

	    			try{
	    				String[] info = contents.split(";");

	    				Location loc = new Location("BIDI");
	    				loc.setLatitude(Double.parseDouble(info[0]));
	    				loc.setLongitude(Double.parseDouble(info[1]));
	    				loc.setAltitude(Double.parseDouble(info[2]));

	    				setCurrentLocation(loc);
	    				setPositionInMap(calculateZoom((double)50));
	    			}catch(Exception e){
	    				Toast.makeText(getBaseContext(), 
	    						"There was an error with BIDI location", 
	    						Toast.LENGTH_LONG).show();
	    			}
	    		}else
	    			Toast.makeText(getBaseContext(), 
	    					"There was an error with BIDI location", 
	    					Toast.LENGTH_LONG).show();
	    		
	    		break;
	
            default:
                break; 
		}
	}
	
    
    private int calculateZoom(double radius){
    	
    	if(radius<200)
    		return 18;
    	if(radius>=200 && radius<400)
    		return 17;
    	if(radius>=400 && radius<700)
    		return 16;
    	if(radius>=700 && radius<1000)
    		return 15;
    	if(radius>=1000 && radius<2000)
    		return 14;
    	if(radius>=2000 && radius<5000)
    		return 13;
    	if(radius>5000 && radius<=15000)
    		return 11;
    	if(radius>15000 && radius<=25000)
    		return 10;
    	if(radius>25000 && radius<=50000)
    		return 9;
    	if(radius>50000 && radius<=75000)
    		return 8;
    	if(radius>75000 && radius<=150000)
    		return 7;
    	if(radius>=150000 && radius<500000)
    		return 6;
    	if(radius>=500000 && radius<1E6)
    		return 5;
    	
    	return 4;
    }
    
	@Override
	protected boolean isRouteDisplayed() {
		// TODO Auto-generated method stub
		return false;
	}
	
//	private Handler handlerRefresh = new Handler() {
//		@Override
//		public void handleMessage(Message msg) {
//			switch(msg.what){
//			case 0:
//				pd.setMessage("Authorizing...");
//				break;
//			case 1:
//				pd.setMessage("Locating...");
//				break;
//			case 2:
//				pd.setMessage("Forbidding...");
//				break;
//			}
//			
//		}
//	};
//	
//	private Handler handlerEnd = new Handler() {
//		@Override
//		public void handleMessage(Message msg) {
//			pd.dismiss();
//			if(msg.what!=0){
//				setCurrentLocation(currentLocation);
//				setPositionInMap(calculateZoom((double)msg.what));
//			}
//			Toast.makeText(getBaseContext(), message,Toast.LENGTH_LONG).show();
//		}
//	};
//	
//	private void runMovistar(){
//		pd = ProgressDialog.show(LocationWays.this, "Localizame", "Connecting...", true);
//		
//		new Thread(){
//			public void run(){
//				int radius = searchMovistar(usrtlf, usrpwd);
//				handlerEnd.sendEmptyMessage(radius);
//				
//			}
//		}.start();
//		
//	}
	
}